package cn.yudao.basic.service.impl;

import cn.yudao.basic.constant.BaseConstants;
import cn.yudao.basic.exception.BusinessException;
import cn.yudao.basic.service.IVerifyCodeService;
import cn.yudao.basic.utils.*;
import cn.yudao.basic.vo.RegisterVo;
import cn.yudao.user.domain.User;
import cn.yudao.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     * @Title: getImgBase
     * @Description: 接收uuid，返回给base编码后的
     * @Author: Mr.Jia
     * @Version: 1.0
     * @Date: 2022/7/4 16:37
     * @Parameters:
     * @Return
     */
    @Override
    public String getImgBase(String item) {
        // 判断传入的值是否为null
        if (item == null && "".equals(item)) {
            throw new BusinessException("请填写参数");
        }
        // 获取到随机的4位的字符串通过StrUtils的方法获取
        String complexRandomString = StrUtils.getComplexRandomString(4);
        // 将传入的uuid作为key，随机的4位字符串作为value，存储到redis中
        redisTemplate.opsForValue().set(item, complexRandomString, 5, TimeUnit.MINUTES);
        // 使用VerifyCodeUtils工具类将字符串添加到一个随机图片中去，并生成Base64的编码字符串
        String baseImg = VerifyCodeUtils.VerifyCode(100, 30, complexRandomString);
        return baseImg;
    }

    /**
     * @Title: smsCode
     * @Description: 手机注册获取手机验证码
     * @Author: Mr.Jia
     * @Version: 1.0
     * @Date: 2022/7/8 21:30
     * @Parameters:
     * @Return
     */
    @Override
    public void smsCode(RegisterVo registerVo) {
        String phone = registerVo.getPhone();
        String type = registerVo.getType();
        // 判断前端传入的参数是否为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)) {
            throw new BusinessException("参数不能为空！");
        }

        // 判断是不是注册业务
        if ("register".equals(type)) {
            String imageCodeValue = registerVo.getImageCodeValue();
            String imageCode = registerVo.getImageCode();
            if ( StringUtils.isEmpty(imageCodeValue) ||
                    StringUtils.isEmpty(imageCode)) {
                throw new BusinessException("参数不能为空！");
            }
            // 比对输入的图片验证码是否正确
            String imgRedis = (String) redisTemplate.opsForValue().get(imageCode);
            // 判断redis中是否存在此验证码
            if (imgRedis == null) {
                throw new BusinessException("验证码为空，请重新输入验证码");
            }
            // 判断用户是否注册过
            User user = userMapper.loadByPhone(phone);
            if (user != null) {
                throw new BusinessException("用户已经存在");
            }
            // 判断用户输入的验证码是否和图片验证码一致
            if (!imgRedis.equalsIgnoreCase(imageCodeValue)) {
                throw new BusinessException("验证码输入错误");
            }
            // 使用抽取的方法发送短信
            sendPhoneCode(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY,phone);

        }else if ("binder".equals(type)){ // 判断是不是绑定业务
            // 判断手机格式是否正确
            if (ValidateUtil.validatePhone(phone)){
                sendPhoneCode(BaseConstants.VerifyCodeConstant.BUSINESS_BINDER_KEY,phone);
            }else {
                throw new BusinessException("请输入正确的手机格式");
            }

        }else if("login".equals(type)){ // 判断是不是登录获取验证码
            String imageCodeValue = registerVo.getImageCodeValue();
            String imageCode = registerVo.getImageCode();
            // 判断前端传入的参数是否为空
            if (registerVo == null) {
                throw new BusinessException("系统繁忙,参数异常");
            } else if (StringUtils.isEmpty(phone) ||
                    StringUtils.isEmpty(imageCodeValue) ||
                    StringUtils.isEmpty(imageCode)) {
                throw new BusinessException("参数不能为空！");
            }
            // 判断手机格式是否正确
            if (!ValidateUtil.validatePhone(phone)) {
                throw new BusinessException("请输入正确的手机号！");
            }
            // 判断用户是否存在
            User user = userMapper.loadByPhone(phone);
            if (user == null) {
                throw new BusinessException("用户不存在请注册！");
            }
            // 判断账号是否被拉黑
            if (user.getState() == 0) {
                throw new BusinessException("此账号被拉黑！");
            }
            // 判断图片验证码是否输入正确
            Object imageCodeValueTmp = redisTemplate.opsForValue().get(imageCode);
            if (StringUtils.isEmpty(imageCodeValueTmp.toString().trim())) {
                throw new BusinessException("图片验证码错误！");
            }
            if (!imageCodeValueTmp.toString().equalsIgnoreCase(imageCodeValue)) {
                throw new BusinessException("图片验证码错误！");
            }
            // 发送验证码
            sendPhoneCode(BaseConstants.VerifyCodeConstant.BUSINESS_LOGIN_KEY,phone);
        }
    }



    /**
    * @Title: sendPhoneCode
    * @Description: 发送手机验证码方法
    * @Author: Mr.Jia
    * @Version: 1.0
    * @Date:  2022/7/10 17:42
    * @Parameters:
    * @Return
    */
    public void sendPhoneCode(String key, String phone){
        // 拼接电话的业务键作为存入到redis的key
        String phoneRedisKey = key + phone;
        // 从redis中通过key获取value
        Object phoneRedisValue = redisTemplate.opsForValue().get(phoneRedisKey);
        // 定义一个空字符串
        String PhoneVerifyCode = "";
        // 判断phoneRedisValue是否存在
        if (phoneRedisValue == null) {
            // 获取随机验证码
            PhoneVerifyCode = StrUtils.getComplexRandomString(4);
        } else {
            // 获取当前时间戳
            long nowTime = System.currentTimeMillis();
            // 获取值中的时间戳 redis中我们value是时间戳：+ 验证码的值
            String[] phoneRedisValueTmp = phoneRedisValue.toString().split(":");
            // 获取值中的时间戳 redis中我们value是时间戳：+ 验证码的值
            Long lastTime = Long.valueOf(phoneRedisValueTmp[0]);
            // 判断间隔时间是否大于1分钟
            if (nowTime - lastTime < 1 * 60 * 1000) {
                throw new BusinessException("请一分钟后在获取验证码");
            }
            // 获取redis中的验证码值
            PhoneVerifyCode = phoneRedisValueTmp[1];
        }
        // 将手机验证码存入到redis中设置时间3分钟
        redisTemplate.opsForValue().set(phoneRedisKey, System.currentTimeMillis() + ":" + PhoneVerifyCode, 3, TimeUnit.MINUTES);
        // 发送短信验证码
//            SendMsgUtils.sendMsg(phone,"您的验证码为:" + PhoneVerifyCode);
        System.out.println("您的验证码为：" + PhoneVerifyCode + "请尽快填写三分钟有效");
    }

    /**
     * @Title: emailCode
     * @Description: 注册获取邮件验证码
     * @Author: Mr.Jia
     * @Version: 1.0
     * @Date: 2022/7/8 21:29
     * @Parameters:
     * @Return
     */
    @Override
    public void emailCode(RegisterVo registerVo) {
        if (registerVo == null) {
            throw new BusinessException("系统繁忙,参数异常");
        }
        // 获得参数
        String email = registerVo.getEmail();
        String imageCodeValue = registerVo.getImageCodeValue();
        String imageCode = registerVo.getImageCode();
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(imageCodeValue) || StringUtils.isEmpty(imageCode)) {
            throw new BusinessException("参数不为空");
        }
        // 判断用户是否注册过
        User user = userMapper.loadByEmail(email);
        if (user != null) {
            throw new BusinessException("用户已注册");
        }
        // 判断图像验证码是否相等
        Object imageRedisCode = redisTemplate.opsForValue().get(imageCode);
        if (imageRedisCode == null) {
            throw new BusinessException("验证码不存在，请重新获取");
        }
        if (!imageCodeValue.equalsIgnoreCase(imageRedisCode.toString())) {
            throw new BusinessException("验证码输入错误");
        }
        // 使用业务键凭借eamil作为redis中的key
        String emailCodeKey = BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + email;
        // 通过业务键去redis中查找是否有value值
        Object emailCodeValueTmp = redisTemplate.opsForValue().get(emailCodeKey);
        long nowTime = System.currentTimeMillis(); // 获取当前时间
        String emailCode = "";
        if (emailCodeValueTmp == null) {
            // 生成邮件验证码
            emailCode = StrUtils.getComplexRandomString(4);
        } else {
            // 说明有值，我们拿到上次发送的邮件发送的时间
            String[] split = emailCodeValueTmp.toString().split(":");
            Long lastTime = Long.valueOf(split[0]);
            if (nowTime - lastTime < 1 * 60 * 1000) {
                throw new BusinessException("请稍后获取");
            }
            emailCode = split[1];
        }
        // 存入到redis中，并设置三分钟有效
        redisTemplate.opsForValue().set(emailCodeKey, System.currentTimeMillis() + ":" + emailCode, 3, TimeUnit.MINUTES);
        // 通过邮件工具类发送邮件
        MailUtils.sendMail(email, "您的验证码为：" + emailCode, "宠物之家注册");
    }

//    /**
//     * @Title: loginPhoneCode
//     * @Description: 登录获取手机验证码
//     * @Author: Mr.Jia
//     * @Version: 1.0
//     * @Date: 2022/7/8 21:24
//     * @Parameters:
//     * @Return
//     */
//    @Override
//    public void loginPhoneCode(RegisterVo registerVo) {
//        String phone = registerVo.getPhone();
//        String imageCodeValue = registerVo.getImageCodeValue();
//        String imageCode = registerVo.getImageCode();
//        // 判断前端传入的参数是否为空
//        if (registerVo == null) {
//            throw new BusinessException("系统繁忙,参数异常");
//        } else if (StringUtils.isEmpty(phone) ||
//                StringUtils.isEmpty(imageCodeValue) ||
//                StringUtils.isEmpty(imageCode)) {
//            throw new BusinessException("参数不能为空！");
//        }
//        // 判断手机格式是否正确
//        if (!ValidateUtil.validatePhone(phone)) {
//            throw new BusinessException("请输入正确的手机号！");
//        }
//        // 判断用户是否存在
//        User user = userMapper.loadByPhone(phone);
//        if (user == null) {
//            throw new BusinessException("用户不存在请注册！");
//        }
//        // 判断账号是否被拉黑
//        if (user.getState() == 0) {
//            throw new BusinessException("此账号被拉黑！");
//        }
//        // 判断图片验证码是否输入正确
//        Object imageCodeValueTmp = redisTemplate.opsForValue().get(imageCode);
//        if (StringUtils.isEmpty(imageCodeValueTmp.toString().trim())) {
//            throw new BusinessException("图片验证码错误！");
//        }
//        if (!imageCodeValueTmp.toString().equalsIgnoreCase(imageCodeValue)) {
//            throw new BusinessException("图片验证码错误！");
//        }
//        // 判断redis中是否存在
//        String loginPhoneRedisKey = BaseConstants.VerifyCodeConstant.BUSINESS_LOGIN_KEY + phone;
//        Object loginPhoneRedisValueTmp = redisTemplate.opsForValue().get(loginPhoneRedisKey);
//        String LoginPhoneCode = "";
//        if (loginPhoneRedisValueTmp == null) {
//            LoginPhoneCode = StrUtils.getComplexRandomString(4);
//        } else {
//            // 根据时间戳判断获取验证码时间有没有间隔1分钟
//            String[] split = loginPhoneRedisValueTmp.toString().split(":");
//            String s = split[0];
//            Long lastTime = Long.valueOf(s);
//            long nowTime = System.currentTimeMillis();
//            if (nowTime - lastTime < 1 * 60 * 1000) {
//                throw new BusinessException("请一分钟后再获取！");
//            }
//            LoginPhoneCode = split[1];
//        }
//        String loginPhoneRedisValue = System.currentTimeMillis() + ":" + LoginPhoneCode;
//        // 通过key，value将数据存入到redis中设置三分钟有效
//        redisTemplate.opsForValue().set(loginPhoneRedisKey, loginPhoneRedisValue, 3, TimeUnit.MINUTES);
//        // 发送短信验证码
////        SendMsgUtils.sendMsg(phone,"您的验证码为:" + LoginPhoneCode);
//        System.out.println("您的验证码为：" + LoginPhoneCode + "请尽快填写三分钟有效");
//    }
}
